//----------------------------------------------------------------rect_base
template<class T> struct rect_base
{
	typedef T            value_type;
	typedef rect_base<T> self_type;
	T x1, y1, x2, y2;
	
	rect_base() {}
	rect_base(T x1_, T y1_, T x2_, T y2_) :
	x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
	
	void init(T x1_, T y1_, T x2_, T y2_) 
	{
		x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; 
	}
	
	const self_type& normalize()
	{
		T t;
		if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
		if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
		return *this;
	}
	
	bool clip(const self_type& r)
	{
		if(x2 > r.x2) x2 = r.x2;
		if(y2 > r.y2) y2 = r.y2;
		if(x1 < r.x1) x1 = r.x1;
		if(y1 < r.y1) y1 = r.y1;
		return x1 <= x2 && y1 <= y2;
	}
	
	bool is_valid() const
	{
		return x1 <= x2 && y1 <= y2;
	}
	
	bool hit_test(T x, T y) const
	{
		return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
	}
};

//-----------------------------------------------------intersect_rectangles
template<class Rect> 
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
{
	Rect r = r1;

	if(r.x2 > r2.x2) r.x2 = r2.x2; 
	if(r.y2 > r2.y2) r.y2 = r2.y2;
	if(r.x1 < r2.x1) r.x1 = r2.x1;
	if(r.y1 < r2.y1) r.y1 = r2.y1;
	return r;
}


//---------------------------------------------------------unite_rectangles
template<class Rect> 
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
{
	Rect r = r1;
	if(r.x2 < r2.x2) r.x2 = r2.x2;
	if(r.y2 < r2.y2) r.y2 = r2.y2;
	if(r.x1 > r2.x1) r.x1 = r2.x1;
	if(r.y1 > r2.y1) r.y1 = r2.y1;
	return r;
}

typedef rect_base<int>    rect_i; //----rect_i
typedef rect_base<float>  rect_f; //----rect_f
typedef rect_base<double> rect_d; //----rect_d
